package server.connector.http;

import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.Logger;
import org.apache.catalina.util.LifecycleSupport;
import org.apache.catalina.util.StringManager;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

//HTTP处理器
public class HttpProcessor implements Lifecycle, Runnable {
    //调用自己的连接器
    private HttpConnector connector = null;
    //处理器编号
    private int id = 0;
    //日志等级
    private int debug = 0;
    //处理器线程名
    private String threadName;
    //服务器端口号
    private int serverPort = 0;
    protected StringManager sm =
            StringManager.getManager(Constants.PACKAGE);
    //构造器
    public HttpProcessor(HttpConnector connector, int id) {
        this.connector = connector;
        this.id = id;
        this.debug = connector.getDebug();
        this.serverPort = connector.getPort();
        this.threadName = "HttpProcessor[" + connector.getPort() + "][" + id + "]";
    }

    //与客户端连接的Socket
    private Socket socket;
    //是否可以获得Socket
    private boolean available = false;
    //唤醒processor
    synchronized void assign(Socket socket) {
        this.socket = socket;
        if ((debug >= 1) && (socket != null))
            log(" An incoming request is being assigned");
        available = true;
        notifyAll();
    }
    //在获得Socket之前,一直阻塞,直到获得到Socket才返回
    private synchronized Socket await() {
        while (!available) {
            try {
                wait();
            } catch (InterruptedException e) {

            }
        }
        available = false;
        if ((debug >= 1) && (socket != null))
            log("  The incoming request has been awaited");
        return this.socket;
    }


    //打印日志
    private void log(String message) {
        Logger logger = connector.getContainer().getLogger();
        if (logger != null) {
            logger.log(threadName + " " + message);
        }
    }
    private void log(String message, Throwable throwable) {
        Logger logger = connector.getContainer().getLogger();
        if (logger != null)
            logger.log(threadName + " " + message, throwable);
    }
    //实现Lifecycle接口------------------------------------------------------------------------------
    private LifecycleSupport lifecycle = new LifecycleSupport(this);
    @Override
    public void addLifecycleListener(LifecycleListener listener) {
        lifecycle.addLifecycleListener(listener);
    }

    @Override
    public LifecycleListener[] findLifecycleListeners() {
        return lifecycle.findLifecycleListeners();
    }

    @Override
    public void removeLifecycleListener(LifecycleListener listener) {
        lifecycle.removeLifecycleListener(listener);
    }

    private boolean started = false;
    //启动处理器线程
    @Override
    public void start() throws LifecycleException {
        if (started)
            throw new LifecycleException(sm.getString("httpProcessor.alreadyStarted"));
        lifecycle.fireLifecycleEvent(START_EVENT, null);
        started = true;
        threadStart();
    }
    private Thread thread = null;
    //启动处理器线程
    private void threadStart() {
        log(sm.getString("httpProcessor.starting"));
        thread = new Thread(this, threadName);
        thread.setDaemon(true);
        thread.start();

        if (debug >= 1)
            log(" Background thread has been started");

    }
    //后续实现
    @Override
    public void stop() throws LifecycleException {

    }

    //实现Runnable接口------------------------------------------------------------------------------
    private boolean stopped = false;
    //不懂
    private Object threadSync = new Object();
    @Override
    public void run() {
        while (!stopped) {
            //阻塞等待,直到有连接需要处理
            Socket socket = await();
            //等待下一个要处理的连接
            if (socket == null)
                continue;
            //处理连接
            try {
                process(socket);
            } catch (Throwable t) {
                log("process.invoke", t);
            }
            //处理完成，把处理器放到栈中等待下次使用
            connector.recycle(this);
        }
        //不懂
        synchronized (threadSync) {
            threadSync.notifyAll();
        }
    }
    private boolean keepAlive = false;
    //处理连接
    private void process(Socket socket) {
        boolean ok = true;
        boolean finishResponse = true;
        SocketInputStream input = null;
        OutputStream output = null;
        //拿到输入流并封装成SocketInputStream
        try {
            input = new SocketInputStream(socket.getInputStream(), connector.getBufferSize());
        } catch (Exception e) {
            log("process.create", e);
            ok = false;
        }

        keepAlive = true;
        while (!stopped && ok && keepAlive) {
            finishResponse = true;

        }


    }

}
